#define DEBUG
#include <cstdio>

using namespace std;

const int maxn=100000;
const long long maxans=10000000000000000;

long long min(long long a, long long b) {
  return a<b ? a : b;
}

long long max(long long a, long long b) {
  return a>b ? a : b;
}

class SegmentTree {
public:
  static const int maxsize=5000000;
  int left[maxsize+1], right[maxsize+1], size;
  long long l[maxsize+1], r[maxsize+1], v[maxsize+1], pos[maxsize+1];

  int newNode(long long l, long long r) {
    size++;
    this->l[size]=l, this->r[size]=r;
    v[size]=pos[size]=-1;
    left[size]=right[size]=0;
    return size;
  }

  void create(long long l, long long r) {
    size=0;
    newNode(l, r);
  } 

  void set(int o, long long t, long long v) {
    if (l[o]==r[o]) {
      this->v[o] = v;
      pos[o] = t;
    } else {
      long long mid=(l[o]+r[o])/2;
      if (t<=mid) {
	if (!left[o]) {
	  left[o] = newNode(l[o], mid);
	}
	set(left[o], t, v);
      } else {
	if (!right[o]) {
	  right[o] = newNode(mid+1, r[o]);
	}
	set(right[o], t, v);
      }
      this->v[o] = pos[o] = -1;
      if (left[o] && this->v[left[o]]>this->v[o]) {
	this->v[o] = this->v[left[o]];
	pos[o] = pos[left[o]];
      }
      if (right[o] && this->v[right[o]]>this->v[o]) {
	this->v[o] = this->v[right[o]];
	pos[o] = pos[right[o]];
      }
    }
  }

  void get(int o, long long tl, long long tr, long long &ret, long long &retpos) {
    if (l[o]==tl && r[o]==tr) {
      if (v[o]>ret) {
	ret = v[o];
	retpos = pos[o];
      }
    } else {
      long long mid=(l[o]+r[o])/2, ret=-1;
      if (tl<=mid && tr>=l[o] && left[o]) {
	get(left[o], max(l[o], tl), min(mid, tr), ret, retpos);
      }
      if (tl<=r[o] && tr>mid && right[o]) {
	get(right[o], max(mid+1, tl), min(r[o], tr), ret, retpos);
      }
    }
  }
};

class Tree {
public:
  int n, m, ind[maxn+1], val[2*maxn-1], to[2*maxn-1], link[2*maxn-1], node[maxn+1];
  long long sum[maxn+1], f[maxn+1];
  
  void addSide(int u, int v, int w) {
    m++;
    to[m] = v;
    val[m] = w;
    link[m] = ind[u];
    ind[u] = m;
  }

  void build(int o, int fa) {
    sum[o] = node[o];
    for (int i=ind[o]; i; i=link[i]) {
      if (to[i]!=fa) {
	build(to[i], o);
	sum[o] += sum[to[i]]-2*val[i];
      }
    }
  }

  bool check(int o, int fa, long long x) {
    static SegmentTree sgt;
    sgt.create(0, maxans);
    int cnt=0;
    for (int i=ind[o]; i; i=link[i]) {
      if (to[i]!=fa) {
	cnt++;
	sgt.set(1, f[to[i]]+val[i]+max(val[i]-sum[to[i]]-f[to[i]], 0), max(sum[to[i]]+f[to[i]]-val[i], 0));
      }
    }
    for (int i=1; i<=cnt; i++) {
      long long k=-1, v=-1;
      sgt.get(1, 0, x, k, v);
      if (v<0) {
	return false;
      } else {
	x = x-v+k;
	sgt.set(1, v, -1);
      }
    }
    return true;
  }

  long long solve(int o, int fa) {
    for (int i=ind[o]; i; i=link[i]) {
      if (to[i]!=fa) {
	f[to[i]] = solve(to[i], o);
      }
    }
    long long ans=0;
    for (long long l=0, r=maxans, mid; l<=r; ) {
      mid = (l+r)/2;
      if (check(o, fa, node[o]+mid)) {
	ans = mid;
	r = mid-1;
      } else {
	l = mid+1;
      }
    }
    return ans;
  }   
};

int main() {
  freopen("horse.in", "r", stdin);
  freopen("horse.out", "w", stdout);

  static Tree tree;
  int n;
  scanf("%d", &n);
  tree.n = n;
  for (int i=1; i<=n; i++) {
    scanf("%d", &tree.node[i]);
  }
  for (int i=1; i<n; i++) {
    int u, v, w;
    scanf("%d %d %d", &u, &v, &w);
    tree.addSide(u, v, w);
    tree.addSide(v, u, w);
  }
  
  tree.build(1, 0);
  printf("%lld", tree.solve(1, 0));

  fclose(stdin);
  fclose(stdout);
  return 0;
}
